/*
 * DAQRun.h
 *
 *  Created on: May 17, 2012
 *      Author: dblyth
 */

#ifndef DAQRUN_H_
#define DAQRUN_H_

#include <pthread.h>
#include <string>
using namespace std;

#include <CAENVMElib.h>

#include <TBranch.h>
#include <TFile.h>
#include <TH1I.h>
#include <TTree.h>

struct configRegister {
	unsigned int address;
	unsigned int value;
	CVDataWidth dataWidth;
};

class DAQRun {
public:
	DAQRun();
	virtual ~DAQRun();

	void addConfigRegister(unsigned int address, unsigned int value, CVDataWidth dataWidth);
	float getADCBufferLevel();
	int getEventCount();
	TH1D* getHistoCopy(const char* name);
	int getHistoCount();
	const char* getHistoName(int index);
	float getMemBufferLevel();
	const char* getRunName();
	bool isRunning();
	void setADCBaseAddress(unsigned int ADCAddress);
	void setDuration(long duration);
	void setNumPedSamples(int num);
	void setRunOff();

	static void* run(void* voidPtr);
	void doRun();

	static void* saveData(void* voidPtr);
	void doSaveData();

private:
	void addToRegisterList(configRegister* newRegister);
	void addToQueue(unsigned char* newEvent);
	unsigned char* removeFromQueue();
	void handleFlag(CVErrorCodes flag);
	string getErrorString(CVErrorCodes error);

	pthread_mutex_t runLock;
	pthread_mutex_t infoLock;

	configRegister** registerList;
	int registerListCount;

	TH1D** histoList;
	int histoListCount;

	unsigned int ADCBaseAddr;
	float ADCBufferLevel;
	int eventCount;
	float memBufferLevel;
	double numPedSamples;
	string runName;
	bool shouldRun;
	bool shouldSaveData;
	long stopTime;

	unsigned int enableMask;
	int numEnabled;
	int wordsPerChannel;

	pthread_t saveDataThread;

	int eventsInQueue;
	unsigned char** queue;
	pthread_mutex_t queueLock;
	pthread_cond_t queueReady;
};

#endif /* DAQRUN_H_ */
